/**
 * 
 */
package com.wisdytech.linkdcs.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.github.pagehelper.PageInfo;
import com.wisdytech.common.bean.Filter;
import com.wisdytech.common.bean.StandardResult;
import com.wisdytech.common.constants.CommonConstants;
import com.wisdytech.common.exception.ServiceException;
import com.wisdytech.common.handler.BaseService;
import com.wisdytech.common.shiro.MyShiroRealm;
import com.wisdytech.common.utils.BaseUtil;
import com.wisdytech.linkdcs.system.dao.ISysResourceDao;
import com.wisdytech.linkdcs.system.dao.ISysRoleResourceDao;
import com.wisdytech.linkdcs.system.model.SysResource;
import com.wisdytech.linkdcs.system.model.SysRoleResource;
import com.wisdytech.linkdcs.system.service.ISystemResourceService;
import com.wisdytech.linkdcs.system.vo.ResourceNodeVO;
import com.wisdytech.linkdcs.system.vo.TreeviewNodeVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.RealmSecurityManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * ClassName: SystemResourceServiceImpl
 * </p>
 * <p>
 * Description: 资源管理业务实现
 * </p>
 * <p>
 * Author: kongming
 * </p>
 * <p>
 * Date: 2017-9-13
 * </p>
 */
@Service("systemResourceService")
@Transactional
public class SystemResourceServiceImpl extends BaseService<ISysResourceDao, SysResource> implements
        ISystemResourceService {



    @Resource
    private ISysResourceDao sysResourceDao;
    
    @Resource
    private ISysRoleResourceDao sysRoleResourceDao;
    
    
    @Override
    public StandardResult addSysResource(SysResource sysResource) {
    	
    	if(StringUtils.isBlank(sysResource.getResCode())) {
    		return StandardResult.getFailResult("资源编码为空");
    	}
    	if(StringUtils.isBlank(sysResource.getResCode())) {
    		return StandardResult.getFailResult("访问地址为空");
    	}
    	if(StringUtils.isBlank(sysResource.getResCode())) {
    		return StandardResult.getFailResult("权限字段为空");
    	}
    	
    	//页面进行判断
		//判断资源编码、访问地址、权限字段不重复
    	EntityWrapper<SysResource> ew =new EntityWrapper<>();
    	ew.eq("RES_CODE", sysResource.getResCode());
    	if(sysResourceDao.selectCount(ew)>0) {
    		throw new ServiceException("资源编码重复");
    	}
    	ew=new EntityWrapper<>();
    	ew.eq("URI", sysResource.getUri());
    	if(sysResourceDao.selectCount(ew)>0) {
    		throw new ServiceException("访问地址重复");
    	}
    	//TODO
    	/*ew=new EntityWrapper<>();
    	ew.eq("PERMISSION", sysResource.getPermission());
    	if(sysResourceDao.selectCount(ew)>0) {
    		throw new ServiceException("权限字段重复");
    	}*/
    	
        sysResource.setPkId(BaseUtil.getUUID());
        sysResource.setEnabled(CommonConstants.RES_ENABLE);
        sysResource.setDelFlag(CommonConstants.DEL_FLAG);
        sysResource.setCreateDate(new Date());
        sysResource.setUpdateDate(new Date());
        sysResource.setCreateUser(BaseUtil.getCurrentUser().getUsername());
        int count;
        count = sysResourceDao.insert(sysResource);
        if (count <= 0) {
            throw new ServiceException("新增失败");
        }
        return StandardResult.getSuccessResult();
    }

    @Override
    public StandardResult delSysResourceById(String ids) {
        for (String id : ids.split(",")) {
            SysResource sysResource = sysResourceDao.selectById(id);
            int num = sysRoleResourceDao.delete(new EntityWrapper<SysRoleResource>().eq("res_id", sysResource.getPkId()));
            int count = sysResourceDao.deleteById(id);
            if (count<=0 || num <=0) {
                throw new ServiceException("删除失败");
            }
        }
        return StandardResult.getSuccessResult();
    }

    @Override
    public StandardResult updateSysResource(SysResource sysResource) {
        int count;
        count = sysResourceDao.updateById(sysResource);
        if (count <= 0) {
            throw new ServiceException("修改失败");
        }
        return StandardResult.getSuccessResult();
    }

    
    @Override
    public PageInfo<SysResource> listSysResources(String resName, String resType, Filter filter) {
        EntityWrapper<SysResource> ew = new EntityWrapper<>();
        if (StringUtils.isNotBlank(resName)) {
            ew.like("res_name", resName);
        }
        if (StringUtils.isNotBlank(resType)) {
            ew.like("res_type", resType);
        }
        List<SysResource> lists = super.beforeList(ISysResourceDao.class, filter).
        			selectList(ew.eq("del_flag", CommonConstants.DEL_FLAG));
        PageInfo<SysResource> resourcePage = new PageInfo<>(lists);
        return resourcePage;
    }

    @Override
    public SysResource getSysResourceById(String id) {
       return sysResourceDao.selectById(id);
    }

    @Override
    public List<SysResource> listAllResource() {
       return sysResourceDao.listAllResource();
    }
    
    @Override
    public List<SysResource> listAllPageResource() {
       return sysResourceDao.listAllPageResource();
    }

    @Override
    public List<SysResource> listSysResourceByRoleId(String roleId) {
        return sysResourceDao.listSysResourceByRoleId(roleId);
    }
    @Override
    public StandardResult saveSysResourceToRoleId(String roleId, String resIds) {
        
        //删除角色全部资源
        EntityWrapper<SysRoleResource> ew = new EntityWrapper<>();
        sysRoleResourceDao.delete(ew.eq("ROLE_ID", roleId));
        
        //新增角色资源
        
        List<String>  resources =JSON.parseArray(resIds, String.class);
        List<SysRoleResource> roleResList =new ArrayList<>();
        for(String resKey : resources){
            SysRoleResource srr =new SysRoleResource();
            srr.setRoleId(roleId);
            srr.setResId(resKey);
            roleResList.add(srr);
        }
        
        sysRoleResourceDao.insertByBatch(roleResList);

        RealmSecurityManager securityManager =
                (RealmSecurityManager) SecurityUtils.getSecurityManager();
        MyShiroRealm myShiroRealm = (MyShiroRealm)securityManager.getRealms().iterator().next();
        //删除权限
        myShiroRealm.getAuthorizationCache().clear();

        return StandardResult.getSuccessResult();
    }

    @Override
    public List<ResourceNodeVO> listRoleResources(String roleId) {
        //获取全部资源
        List<SysResource> allResource =listAllResource();
        //获取角色资源
        List<String> roleResource = sysRoleResourceDao.listUserResource(roleId);
        return getRoleUsedResoure(allResource, roleResource);
    }

    @Override
    public List<ResourceNodeVO> getRoleResources(List<String> roleIds) {
        //获取全部资源
        //TODO 测试阶段，没有角色会返回所有资源
        if(roleIds == null|| roleIds.size() == 0) {
            return null;
        }
        List<SysResource> moduleAndPageResources = sysResourceDao.getPageAndModuleResource();
        List<String> roleResource = sysResourceDao.getSysResourceByUserRole(roleIds);
        //获取角色资源
        return  getRoleUsedResoure(moduleAndPageResources, roleResource);
    }

    @Override
    public List<ResourceNodeVO> getSuperAdminResources() {
        List<SysResource> moduleAndPageResources = sysResourceDao.getPageAndModuleResource();
        List<String> roleResource = sysResourceDao.getSysResourceByUserRole(null);
        //获取角色资源
        return  getRoleUsedResoure(moduleAndPageResources, roleResource);
    }

    /**
     * 重写获取资源树方法以前方法弃用
     * @param roleId 角色id
     * @return
     */
    @Override
	public List<TreeviewNodeVO> getResourceTree(String roleId) {
    	//获取全部资源
        List<SysResource> allResource =listAllResource();
        //获取角色资源
        List<String> roleResource= sysRoleResourceDao.listUserResource(roleId);
        return getRoleUsedResoure2(allResource, roleResource);
	}
    
    

	/**
     * 
     * <p>Description: 获取用户用户资源列表</p>
     * @param allResource 全部资源列表
     * @param roleResource 用户拥有资源列表
     * @return 标记后的资源列表
     */
    private List<ResourceNodeVO> getRoleUsedResoure(List<SysResource> allResource,List<String> roleResource){
        
        //节点
        List<ResourceNodeVO> usedResources=new ArrayList<ResourceNodeVO>();
        
        for(SysResource sysResource :allResource){
            //无父类
            if(StringUtils.isBlank(sysResource.getParentId())){
                ResourceNodeVO parentNode=new ResourceNodeVO(sysResource.getPkId(),sysResource.getResName(),"",sysResource.getUri());
                parentNode.setCode(sysResource.getResCode());
                parentNode.setIconCls(sysResource.getIconCls());
                parentNode.setBelongSystem(sysResource.getBelongSystem());
                //判断用户是否拥有
                if(roleResource.contains(sysResource.getPkId())){
                    parentNode.setEnable(true);
                }
                //获取子资源
                getChildNodes(allResource, roleResource, parentNode);
                usedResources.add(parentNode);
            }  
            
            
        }
        return usedResources;
        
    }
    
    private List<TreeviewNodeVO> getRoleUsedResoure2(List<SysResource> allResource,List<String> roleResource){
        
        //节点
        List<TreeviewNodeVO> usedResources=new ArrayList<>();
        
        for(SysResource sysResource :allResource){
            //无父类
            if(StringUtils.isBlank(sysResource.getParentId())){
            	TreeviewNodeVO parentNode=new TreeviewNodeVO();
            	parentNode.setId(sysResource.getPkId());
            	parentNode.setText(sysResource.getResName());
                //判断用户是否拥有
                if(roleResource.contains(sysResource.getPkId())){
                	Map<String, Object> state = new HashMap<>();
                	state.put("checked", true);
                	parentNode.setState(state);
                }else {
                	Map<String, Object> state = new HashMap<>();
                	state.put("checked", false);
                	parentNode.setState(state);
                }
                //获取子资源
                getChildNodes2(allResource, roleResource, parentNode);
                usedResources.add(parentNode);
            }  
            
            
        }
        return usedResources;
        
    }
    
    /**
     * 
     * <p>Description: 循环获取子节点</p>
     * @param allResource
     * @param roleResource
     * @param parentNode
     * @return
     */
    private ResourceNodeVO getChildNodes(List<SysResource> allResource,List<String> roleResource,ResourceNodeVO parentNode){
        List<ResourceNodeVO> childNodes=new ArrayList<ResourceNodeVO>();
        for(SysResource sysResource :allResource){
            //子节点
            if(parentNode.getId().equals(sysResource.getParentId())){
            	ResourceNodeVO childNode=new ResourceNodeVO(
                        sysResource.getPkId(),sysResource.getResName(),parentNode.getId(),sysResource.getUri()); 
            	childNode.setCode(sysResource.getResCode());
            	childNode.setBelongSystem(sysResource.getBelongSystem());
            	//判断用户是否拥有
                if(roleResource.contains(sysResource.getPkId())){
                    childNode.setEnable(true);
//                	continue;
                }
                
                childNodes.add(childNode);
                this.getChildNodes(allResource, roleResource, childNode);
            }
        }
        //子节点列表
        parentNode.setChildren(childNodes);
        return parentNode;
        
    }
    
    /**
     * 
     * <p>Description: 循环获取子节点</p>
     * @param allResource
     * @param roleResource
     * @param parentNode
     * @return
     */
    private TreeviewNodeVO getChildNodes2(List<SysResource> allResource,List<String> roleResource,TreeviewNodeVO parentNode){
        List<TreeviewNodeVO> childNodes=new ArrayList<TreeviewNodeVO>();
        for(SysResource sysResource :allResource){
            //子节点
            if(parentNode.getId().equals(sysResource.getParentId())){
            	TreeviewNodeVO childNode=new TreeviewNodeVO();
                childNode.setId(sysResource.getPkId());
                childNode.setParentId(parentNode.getId());
            	childNode.setText(sysResource.getResName());
                //判断用户是否拥有
                if(roleResource.contains(sysResource.getPkId())){
                	Map<String, Object> state = new HashMap<>();
                	state.put("checked", true);
                	childNode.setState(state);
                }else {
                	Map<String, Object> state = new HashMap<>();
                	state.put("checked", false);
                	parentNode.setState(state);
                }
                
                childNodes.add(childNode);
                this.getChildNodes2(allResource, roleResource, childNode);
            }
        }
        //子节点列表
        parentNode.setNodes(childNodes);;
        return parentNode;
        
    }

	@Override
	public List<SysResource> listPageResource(String parentId) {
		EntityWrapper<SysResource> ew = new EntityWrapper<>();
		if(StringUtils.isBlank(parentId)) {
			ew.eq("PARENT_ID","");
		}else {
			ew.eq("PARENT_ID", parentId);
		}
		ew.eq("RES_TYPE", 0);
		ew.eq("ENABLED", 0);
		ew.eq("DEL_FLAG",0);
		ew.orderBy("RES_ORDER");
		
		return sysResourceDao.selectList(ew);
	}

	@Override
	public List<TreeviewNodeVO> getParentResourceTree(String parentId) {
		//获取全部资源
        List<SysResource> allResource =listAllResource();
        //获取角色资源
        List<String> roleResource= new ArrayList<>();
        roleResource.add(parentId);
        return getRoleUsedResoure2(allResource, roleResource);
	}

    @Override
    public String getParentNode(String resCode) {
        if(StringUtils.isBlank(resCode)) {
            return "";
        }
        String parentNode = "";
        EntityWrapper<SysResource> ew = new EntityWrapper<>();
        ew.setSqlSelect("parent_id")
                .eq("belong_system","1")
                .eq("res_code",resCode)
                .eq("enabled","1")
                .eq("del_flag","0");
        String parentId = Optional.ofNullable(sysResourceDao.selectList(ew))
                .filter(resourceList -> resourceList.size()>0)
                .map(resourceList -> resourceList.get(0))
                .map(SysResource::getParentId)
                .orElse("");
        if (StringUtils.isNotBlank(parentId)) {
            parentNode = getResCodeById(resCode,parentId);
        }
        return parentNode;
    }

    private String getResCodeById(String resCode,String pkId) {
        if(StringUtils.isBlank(pkId)) {
            return "";
        }
        EntityWrapper<SysResource> ew = new EntityWrapper<>();
        ew.setSqlSelect("parent_id","res_code")
                //.eq("belong_system","1")
                .eq("pk_id",pkId)
                .eq("enabled","1")
                .eq("del_flag","0");
        Optional<List<SysResource>> optional = Optional.ofNullable(sysResourceDao.selectList(ew));
        String resCode2 = optional.filter(resourceList -> resourceList.size()>0)
                .map(resourceList -> resourceList.get(0))
                .map(SysResource::getResCode)
                .orElse("");
        if(StringUtils.isNotBlank(resCode2)) {
            resCode = resCode2+"-"+resCode;
        }
        String parentId = optional.filter(resourceList -> resourceList.size()>0)
                .map(resourceList -> resourceList.get(0))
                .map(SysResource::getParentId)
                .orElse("");
        if(StringUtils.isNotBlank(parentId)) {
            resCode = getResCodeById(resCode,parentId);
        }
        return resCode;
    }
}
